from sqlalchemy.orm import Session
from fastapi import APIRouter, Depends
from app.db.database import get_db
from fastapi.security import OAuth2PasswordBearer

from app.schema.user_schema import UserLogin, UserLoginResponse, UserCreate,UserInfoResponse,ChangePasswordRequest,UpdateUserInfoRequest,UpdateUserPermissionsRequest
from app.services import user_service
from app.utilities.error import Error
from app.utilities.response import SuccessResponse
from fastapi import Query

from app.schema.user_schema import UserLogin, UserLoginResponse, UserCreate,UserInfoResponse,ChangePasswordRequest,UserWithPermissionsResponse
from app.services import user_service
from app.utilities.error import Error
from typing import List
from fastapi import Body


from ..utilities.jwt_token import decode_token
router = APIRouter(prefix="/users", tags=["users"])

@router.post("/login", response_model=UserLoginResponse)
def login(user: UserLogin, db: Session = Depends(get_db)):
    return user_service.login_user(db, user)


@router.post("/register", response_model=UserLoginResponse)
def register(user: UserCreate, db: Session = Depends(get_db)):
    return user_service.register_user(db, user)


oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


@router.get("/me", response_model=UserInfoResponse)
def get_my_info(token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)):
    if not token:
        raise Error.unauthorized("Missing token")

    try:
        payload = decode_token(token)
    except Exception as e:
        raise Error.unauthorized(f"Invalid token: {str(e)}")

    user_id = payload.get("sub")
    if not user_id:
        raise Error.unauthorized("Invalid token: no subject")

    return user_service.get_user_info(db, user_id)




@router.put("/change-password")
def change_password(
    request: ChangePasswordRequest,
    token: str = Depends(oauth2_scheme),
    db: Session = Depends(get_db)
):
    if not token:
        raise Error.unauthorized("Missing token")
    try:
        payload = decode_token(token)
    except Exception:
        raise Error.unauthorized("Invalid token")

    user_id = payload.get("sub")
    if not user_id:
        raise Error.unauthorized("Invalid token payload")

    return user_service.change_password(db, user_id, request)



@router.get("/list-users")
def list_users(
    skip: int = Query(0, ge=0),
    limit: int = Query(10, ge=1),
    token: str = Depends(oauth2_scheme),
    db: Session = Depends(get_db)
):
    if not token:
        raise Error.unauthorized("Missing token")
    try:
        payload = decode_token(token)
    except Exception:
        raise Error.unauthorized("Invalid token")

    user_id = payload.get("sub")
    if not user_id:
        raise Error.unauthorized("Invalid token payload")

    role = payload.get("role")
    if role != "Admin":
        raise Error.unauthorized("Only admin users can access this endpoint")

    data = user_service.list_users(db, skip, limit)
    return SuccessResponse.ok("Fetched users successfully", data)


@router.put("/profile")
def update_profile(
    request: UpdateUserInfoRequest,
    token: str = Depends(oauth2_scheme),
    db: Session = Depends(get_db)
):
    if not token:
        raise Error.unauthorized("Missing token")

    try:
        payload = decode_token(token)
    except Exception:
        raise Error.unauthorized("Invalid token")

    user_id = payload.get("sub")
    if not user_id:
        raise Error.unauthorized("Invalid token payload")

    user = user_service.update_user_info(db, user_id, request)
    return SuccessResponse.ok("Profile updated successfully")


@router.put("/update-permissions")
def update_user_permissions(
        request: UpdateUserPermissionsRequest = Body(...),
        token: str = Depends(oauth2_scheme),
        db: Session = Depends(get_db)
):
    if not token:
        raise Error.unauthorized("Missing token")
    payload = decode_token(token)
    if not payload:
        raise Error.unauthorized("Invalid token")

    role = payload.get("role")
    if role != "Admin":
        raise Error.unauthorized("Only admin users can update permissions")

    user = user_service.update_user_permissions_by_email(db, request.email, request.permission_ids)
    return SuccessResponse.ok("Permissions updated successfully", {
        "email": user.email,
        "updated_permissions": request.permission_ids
    })



